﻿using Newtonsoft.Json.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Serialization;

namespace CommonlyUtils
{
    /// <summary>
    /// 静态扩展类
    /// </summary>
    public static class StringExtension
    {
        /// <summary>
        /// 时间格式化为字符串
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns>JSON字符串</returns>
        public static string ToStr(this DateTime dtime)
        {
            return dtime.ToString("yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>
        /// JSON序列化
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns>JSON字符串</returns>
        public static string ToJson(this object? obj)
        {
            try
            {
                if (obj == null || string.IsNullOrWhiteSpace(obj.ToString()))
                {
                    return "";
                }
                var jsonSerializerSettings = new JsonSerializerSettings { DateFormatString = "yyyy-MM-dd HH:mm:ss" };
                return JsonConvert.SerializeObject(obj, jsonSerializerSettings);
            }
            catch
            {
                return string.Empty;
            }
        }
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T">对象</typeparam>
        /// <param name="json">JSON字符串</param>
        /// <returns>对象</returns>
        public static T GetModelByJson<T>(this string json)
        {
            IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
            timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";

            return JsonConvert.DeserializeObject<T>(json, timeFormat);

        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T">对象</typeparam>
        /// <param name="json">JSON字符串</param>
        /// <returns>对象</returns>
        public static T GetModelByJson<T>(this object json)
        {
            IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
            timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";

            return JsonConvert.DeserializeObject<T>(json.ToString(), timeFormat);
            //}
            //catch
            //{
            //    return default(T);
            //}
        }


        /// <summary>
        /// 是否为空  true 空  false非空
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool IsNull(this string obj)
        {
            if (string.IsNullOrWhiteSpace(obj))
            {
                return true;
            }

            if (obj.Length == 0)
            {
                return true;
            }

            return false;
        }

        public static bool IsNull(this object obj)
        {
            if (obj == null)
            {
                return true;
            }

            if (string.IsNullOrWhiteSpace(obj.ToString()))
            {
                return true;
            }

            if (obj.ToString().Length == 0)
            {
                return true;
            }

            return false;
        }

        public static Dictionary<string, object> ToDictionary(this string json)
        {
            Dictionary<string, object> dictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
            foreach (string item in dictionary.Keys.ToList())
            {
                if (dictionary[item] == null)
                {
                    dictionary.Remove(item);
                }
                else if (dictionary[item].GetType() == typeof(DateTime))
                {
                    dictionary[item] = Convert.ToDateTime(dictionary[item]).ToString("yyyy-MM-dd HH:mm:ss");
                }
            }

            return dictionary;
        }

        public static Dictionary<string, object> ToDictionaryWithKeyToLower(this string json)
        {
            Dictionary<string, object> dictionary = json.ToString().ToDictionary();
            Dictionary<string, object> dictionary2 = new Dictionary<string, object>();
            foreach (KeyValuePair<string, object> item in dictionary)
            {
                if (!dictionary2.ContainsKey(item.Key.ToLower()) && item.Value != null)
                {
                    dictionary2.Add(item.Key.ToLower(), item.Value);
                }
            }

            return dictionary2;
        }

        public static List<Dictionary<string, object>> ToDictionaryList(this string json)
        {
            List<Dictionary<string, object>> list = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(json);
            for (int i = 0; i < list.Count; i++)
            {
                foreach (string item in list[i].Keys.ToList())
                {
                    if (!list[i][item].IsNull() && list[i][item].GetType() == typeof(DateTime))
                    {
                        list[i][item] = Convert.ToDateTime(list[i][item]).ToString("yyyy-MM-dd HH:mm:ss");
                    }
                }
            }

            return list;
        }

        public static Dictionary<string, object> ToDictionary(this object json)
        {
            return json.ToString().ToDictionary();
        }

        public static Dictionary<string, object> ToDictionaryWithKeyToLower(this object json)
        {
            Dictionary<string, object> dictionary = json.ToString().ToDictionary();
            Dictionary<string, object> dictionary2 = new Dictionary<string, object>();
            foreach (KeyValuePair<string, object> item in dictionary)
            {
                if (!dictionary2.ContainsKey(item.Key.ToLower()) && item.Value != null)
                {
                    dictionary2.Add(item.Key.ToLower(), item.Value);
                }
            }

            return dictionary2;
        }

        public static List<Dictionary<string, object>> ToDictionaryList(this object json)
        {
            return json.ToString().ToDictionaryList();
        }

        public static string GetBetweenChar(this string srcstr, string startChar, string endChar, bool inStartChar = false, bool inEndChar = false)
        {
            if (srcstr.IsNull())
            {
                return "";
            }

            int num = srcstr.IndexOf(startChar);
            if (startChar == "" || num == -1)
            {
                num = 0;
            }
            else if (!inStartChar)
            {
                num += startChar.Length;
            }

            int num2 = srcstr.Remove(0, num).IndexOf(endChar);
            if (endChar == "" || num2 == -1)
            {
                num2 = srcstr.Length - num;
            }
            else if (inEndChar)
            {
                num2 += endChar.Length;
            }

            return srcstr.Substring(num, num2);
        }
    }

    /// <summary>
    /// 重写json序列化Key为小写
    /// </summary>
    /// <seealso cref="DefaultContractResolver" />
    public class ToLowerPropertyNamesContractResolver : DefaultContractResolver
    {
        /// <summary>
        /// 重写json序列化Key为小写
        /// </summary>
        public ToLowerPropertyNamesContractResolver()
        {
            base.NamingStrategy = new NamingStrategyToLower();
        }
    }

    /// <summary>
    /// 重写json序列化Key为小写
    /// </summary>
    /// <seealso cref="NamingStrategy" />
    public class NamingStrategyToLower : NamingStrategy
    {
        /// <summary>
        /// 重写json序列化Key为小写
        /// </summary>
        /// <param name="name">The property name to resolve.</param>
        /// <returns>The resolved property name.</returns>
        protected override string ResolvePropertyName(string name)
        {
            return name.ToLower();
        }
    }
}
